using System;
using Headspring.Training.Core.Model;
using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;

namespace Headspring.Training.UnitTests.Model
{
	[TestFixture]
	public class WorkOrderTester
	{
		[Test]
		public void PropertiesShouldGetAndSetValuesProperly()
		{
			var workOrder = new WorkOrder();
			Guid guid = Guid.NewGuid();
			var creator = new Employee();
			var assignee = new Employee();
			var createdDate = new DateTime(2000, 1, 1);
			var completedDate = new DateTime(2000, 10, 1);

			workOrder.Id = guid;
			workOrder.Title = "Title";
			workOrder.Description = "Description";
			workOrder.Status = WorkOrderStatus.Complete;
			workOrder.Number = "Number";
			workOrder.Creator = creator;
			workOrder.Assignee = assignee;
			workOrder.CreatedDate = createdDate;
			workOrder.CompletedDate = completedDate;

			Assert.That(workOrder.Id, Is.EqualTo(guid));
			Assert.That(workOrder.Title, Is.EqualTo("Title"));
			Assert.That(workOrder.Description, Is.EqualTo("Description"));
			Assert.That(workOrder.Status, Is.EqualTo(WorkOrderStatus.Complete));
			Assert.That(workOrder.Number, Is.EqualTo("Number"));
			Assert.That(workOrder.Creator, Is.EqualTo(creator));
			Assert.That(workOrder.Assignee, Is.EqualTo(assignee));
			Assert.That(workOrder.CreatedDate, Is.EqualTo(createdDate));
			Assert.That(workOrder.CompletedDate, Is.EqualTo(completedDate));
		}

		[Test]
		public void PropertiesShouldInitializeToProperDefaults()
		{
			var workOrder = new WorkOrder();
			Assert.That(workOrder.Id, Is.EqualTo(Guid.Empty));
			Assert.That(workOrder.Title, Is.EqualTo(string.Empty));
			Assert.That(workOrder.Description, Is.EqualTo(string.Empty));
			Assert.That(workOrder.Status, Is.EqualTo(WorkOrderStatus.Draft));
			Assert.That(workOrder.Number, Is.EqualTo(null));
			Assert.That(workOrder.Creator, Is.EqualTo(null));
			Assert.That(workOrder.Assignee, Is.EqualTo(null));
			Assert.That(workOrder.CreatedDate, Is.EqualTo(null));
			Assert.That(workOrder.CompletedDate, Is.EqualTo(null));
			Assert.That(workOrder.LastChangeDate, Is.EqualTo(null));
		}

		[Test]
		public void ShouldAddHistoryWhenStatusChanges()
		{
			var workOrder = new WorkOrder();
			workOrder.Status = WorkOrderStatus.Cancelled;

			var employee = new Employee("jsmith", "john", "smith", "jsmith@yahoo.com");
			workOrder.Creator = employee;

			workOrder.ChangeStatus(WorkOrderStatus.InProgress, employee,
			                       new DateTime(2000, 1, 1));

			HistoryEntry[] entries = workOrder.GetHistory();

			Assert.That(entries.Length, Is.EqualTo(1));
			Assert.That(entries[0].BeginStatus,
			            Is.EqualTo(WorkOrderStatus.Cancelled));
			Assert.That(entries[0].EndStatus,
			            Is.EqualTo(WorkOrderStatus.InProgress));
			Assert.That(entries[0].EmployeeFirstName, Is.EqualTo("john"));
		}

		[Test]
		public void ShouldChangeStatus()
		{
			var order = new WorkOrder {Status = WorkOrderStatus.Draft};
			order.ChangeStatus(WorkOrderStatus.Assigned, new Employee(), DateTime.Now);
			Assert.That(order.Status, Is.EqualTo(WorkOrderStatus.Assigned));
		}

		[Test]
		public void ShouldGetAllHistoryEntries()
		{
			var workOrder = new WorkOrder();
			var historyEntry1 = new HistoryEntry(new Employee(),
			                                     WorkOrderStatus.Assigned,
			                                     WorkOrderStatus.InProgress,
			                                     new DateTime(1999, 1, 1));
			var historyEntry2 = new HistoryEntry(new Employee(),
			                                     WorkOrderStatus.Assigned,
			                                     WorkOrderStatus.InProgress,
			                                     new DateTime(2000, 1, 1));
			workOrder.AddHistory(historyEntry1);
			workOrder.AddHistory(historyEntry2);

			HistoryEntry[] entries = workOrder.GetHistory();

			Assert.That(entries.Length, Is.EqualTo(2));
			Assert.That(entries[0].ChangeDate,
			            Is.EqualTo(new DateTime(2000, 1, 1)));
			Assert.That(entries[1].ChangeDate,
			            Is.EqualTo(new DateTime(1999, 1, 1)));
		}

		[Test]
		public void ShouldShowFriendlyStatusValuesAsStrings()
		{
			var workOrder = new WorkOrder {Status = WorkOrderStatus.Assigned};

			Assert.That(workOrder.FriendlyStatus, Is.EqualTo("Assigned"));
		}

		[Test]
		public void ToStringShouldReturnWONumber()
		{
			var order = new WorkOrder {Number = "456"};
			Assert.That(order.ToString(), Is.EqualTo("Work Order 456"));
		}
	}
}